package edu.map.aamas.gui;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.geom.Ellipse2D;
import java.awt.geom.GeneralPath;
import java.awt.geom.Point2D;
import java.awt.geom.QuadCurve2D;

public class Tadpole {
	
	private static int TAIL_LENGTH = 60;
	private static int TAIL_PARTITION = 30;
	private static int HEAD_RADIUS = 10;
	
	public static double FORCE_ANGLE_FACTOR = Math.toRadians(60);
	public static double MOVEMENT_SPEED_FACTOR = 100;
	private static double TAIL_ANGLE_FACTOR = 3;
	private static Point2D.Double defaultPosition = new Point2D.Double(60,60);
	private Point2D.Double realPosition = new Point2D.Double(defaultPosition.x, defaultPosition.y);
	private Point2D.Double paintedPosition = new Point2D.Double(defaultPosition.x, defaultPosition.y);
	private double angle = Math.toRadians(0);
	private double tailAngle = 0.0;
	
	private Color darkColor = Color.BLACK;
	private Color brightColor = new Color(150, 175, 10);
	
	public double instantSpeed = 0.0;
	public double angularSpeed = 0.0;
	
	private static Tadpole instance = null;
	
	public static Tadpole getInstance() {
		if (instance == null)
			instance = new Tadpole();
		return instance;
	}
	
	public static Tadpole resetInstance() {
		if (instance == null)
			return getInstance();
		
		instance.paintedPosition.setLocation(defaultPosition.x, defaultPosition.y);
		instance.realPosition.setLocation(defaultPosition.x, defaultPosition.y);
		instance.setAngle(Math.toRadians(0));
		instance.setTailAngle(0);
		instance.angularSpeed = 0.0;
		instance.instantSpeed = 0.0;
		return instance;
	}
	
	public void paint(PondPanel pond, Graphics2D g) {
		g.translate(paintedPosition.x, paintedPosition.y);
		g.rotate(angle);
		
		double cy = Math.cos(tailAngle) * TAIL_PARTITION;
		double cx = Math.sin(tailAngle) * TAIL_PARTITION;
		GeneralPath gp = new GeneralPath();
		gp.moveTo(-HEAD_RADIUS, 0);
		gp.quadTo(cx-12, cy, 0, TAIL_LENGTH+HEAD_RADIUS);		
		gp.quadTo(cx+12, cy, HEAD_RADIUS, 0);
		gp.closePath();
		g.setColor(brightColor);
		g.fill(gp);
		g.setColor(darkColor);
		g.draw(new QuadCurve2D.Double(0, 0, cx, cy, 0, TAIL_LENGTH+HEAD_RADIUS));
		g.rotate(-tailAngle);
		g.fill(new Ellipse2D.Double(-HEAD_RADIUS-1, -HEAD_RADIUS+3, HEAD_RADIUS * 2+2, HEAD_RADIUS * 2+6));
		g.setColor(brightColor);
		g.drawLine(-3, -2, -3, -2);
		g.drawLine(3, -2, 3, -2);
		
	}


	public Point2D.Double getPosition() {
		return realPosition;
	}


	public void setPosition(Point2D.Double position) {
		this.realPosition = position;
	}

	
	public void setPosition(double x, double y) {
		realPosition.setLocation(x, y);
	}


	public double getAngle() {
		return angle;
	}


	public void setAngle(double angle) {
		this.angle = angle;
	}


	public double getTailAngle() {
		return tailAngle;
	}


	public void setTailAngle(double tailAngle) {
		this.tailAngle = tailAngle;
	}


	public void applyForce(double force, int width, int height) {
		
		//force = Math.max(force, -1);
		//force = Math.min(force, 1);
		
		double prevAngle = getTailAngle();
		setTailAngle(force * FORCE_ANGLE_FACTOR);
		//System.out.println(getTailAngle());
		double deltaAngle = getTailAngle() - prevAngle;		
		
		if (Math.abs(tailAngle) < 0.001)
			tailAngle = 0;
		setTailAngle(tailAngle * 0.96);
		
		prevAngle = getAngle();
		double newAngle = getAngle() + TAIL_ANGLE_FACTOR * deltaAngle ;
		setAngle(newAngle);
		
		double speed = MOVEMENT_SPEED_FACTOR * Math.abs(deltaAngle);
		double dx = Math.sin(getAngle()) * speed;
		double dy = -Math.cos(getAngle()) * speed;
		instantSpeed = Math.sqrt(dx*dx + dy*dy);
		angularSpeed = deltaAngle;
		

		
		setPosition(getPosition().x + dx, getPosition().y+dy+ 0.5);
		
		paintedPosition.x = getPosition().x % width;
		paintedPosition.y = getPosition().y % height;
		
		if (paintedPosition.x < 0)
			paintedPosition.x = width + paintedPosition.x;
		
		if (paintedPosition.y < 0)
			paintedPosition.y = height + paintedPosition.y;
		
		
	}

	public Point2D.Double getPaintedPosition() {
		return paintedPosition;
	}
}
